home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 6 / QRZ Ham Radio Callsign Database - Volume 6.iso / pc / files / amiga / asrc29p.lha / slip.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-29  |  3.9 KB  |  194 lines

  1. /* Send and receive IP datagrams on serial lines. Compatible with SLIP
  2.  * under Berkeley Unix.
  3.  */
  4. #include <stdio.h>
  5. #include "global.h"
  6. #include "mbuf.h"
  7. #include "iface.h"
  8. #include "ax25.h"
  9. #include "slip.h"
  10. #include "amiga/asy.h"
  11. #include "trace.h"
  12.  
  13. int Nslip;
  14.  
  15. static struct mbuf *slip_decode __ARGS((int dev,char c));
  16. static struct mbuf *slip_encode __ARGS((struct mbuf *bp));
  17.  
  18. /* Slip level control structure */
  19. struct slip Slip[ASY_MAX];
  20.  
  21. /* Send routine for point-to-point slip
  22.  * This is a trivial function since there is no slip link-level header
  23.  */
  24. int
  25. slip_send(bp,iface,gateway,prec,del,tput,rel)
  26. struct mbuf *bp;    /* Buffer to send */
  27. struct iface *iface;    /* Pointer to interface control block */
  28. int32 gateway;        /* Ignored (SLIP is point-to-point) */
  29. int prec;
  30. int del;
  31. int tput;
  32. int rel;
  33. {
  34.     if(iface == NULLIF){
  35.         free_p(bp);
  36.         return -1;
  37.     }
  38.     iface->rawsndcnt++;
  39.     return (*iface->raw)(iface,bp);
  40. }
  41. /* Send a raw slip frame -- also trivial */
  42. int
  43. slip_raw(iface,bp)
  44. struct iface *iface;
  45. struct mbuf *bp;
  46. {
  47.     struct mbuf *bp1;
  48.  
  49.     dump(iface,IF_TRACE_OUT,Slip[iface->xdev].type,bp);
  50.     if((bp1 = slip_encode(bp)) == NULLBUF){
  51.         free_p(bp);
  52.         return -1;
  53.     }
  54.     return Slip[iface->xdev].send(iface->dev,bp1);
  55. }
  56. /* Encode a packet in SLIP format */
  57. static
  58. struct mbuf *
  59. slip_encode(bp)
  60. struct mbuf *bp;
  61. {
  62.     struct mbuf *lbp;    /* Mbuf containing line-ready packet */
  63.     register char *cp;
  64.     char c;
  65.  
  66.     /* Allocate output mbuf that's twice as long as the packet.
  67.      * This is a worst-case guess (consider a packet full of FR_ENDs!)
  68.      */
  69.     lbp = alloc_mbuf((int16)(2*len_p(bp) + 2));
  70.     if(lbp == NULLBUF){
  71.         /* No space; drop */
  72.         free_p(bp);
  73.         return NULLBUF;
  74.     }
  75.     cp = lbp->data;
  76.  
  77.     /* Flush out any line garbage */
  78.     *cp++ = FR_END;
  79.  
  80.     /* Copy input to output, escaping special characters */
  81.     while(pullup(&bp,&c,1) == 1){
  82.         switch(uchar(c)){
  83.         case FR_ESC:
  84.             *cp++ = FR_ESC;
  85.             *cp++ = T_FR_ESC;
  86.             break;
  87.         case FR_END:
  88.             *cp++ = FR_ESC;
  89.             *cp++ = T_FR_END;
  90.             break;
  91.         default:
  92.             *cp++ = c;
  93.         }
  94.     }
  95.     *cp++ = FR_END;
  96.     lbp->cnt = cp - lbp->data;
  97.     return lbp;
  98. }
  99. /* Process incoming bytes in SLIP format
  100.  * When a buffer is complete, return it; otherwise NULLBUF
  101.  */
  102. static
  103. struct mbuf *
  104. slip_decode(dev,c)
  105. int dev;    /* Slip unit number */
  106. char c;        /* Incoming character */
  107. {
  108.     struct mbuf *bp;
  109.     register struct slip *sp;
  110.  
  111.     sp = &Slip[dev];
  112.     switch(uchar(c)){
  113.     case FR_END:
  114.         bp = sp->rbp;
  115.         sp->rbp = NULLBUF;
  116.         sp->rcnt = 0;
  117.         return bp;    /* Will be NULLBUF if empty frame */
  118.     case FR_ESC:
  119.         sp->escaped = 1;
  120.         return NULLBUF;
  121.     }
  122.     if(sp->escaped){
  123.         /* Translate 2-char escape sequence back to original char */
  124.         sp->escaped = 0;
  125.         switch(uchar(c)){
  126.         case T_FR_ESC:
  127.             c = FR_ESC;
  128.             break;
  129.         case T_FR_END:
  130.             c = FR_END;
  131.             break;
  132.         default:
  133.             sp->errors++;
  134.             break;
  135.         }
  136.     }
  137.     /* We reach here with a character for the buffer;
  138.      * make sure there's space for it
  139.      */
  140.     if(sp->rbp == NULLBUF){
  141.         /* Allocate first mbuf for new packet */
  142.         if((sp->rbp1 = sp->rbp = alloc_mbuf(SLIP_ALLOC)) == NULLBUF)
  143.             return NULLBUF; /* No memory, drop */
  144.         sp->rcp = sp->rbp->data;
  145.     } else if(sp->rbp1->cnt == SLIP_ALLOC){
  146.         /* Current mbuf is full; link in another */
  147.         if((sp->rbp1->next = alloc_mbuf(SLIP_ALLOC)) == NULLBUF){
  148.             /* No memory, drop whole thing */
  149.             free_p(sp->rbp);
  150.             sp->rbp = NULLBUF;
  151.             sp->rcnt = 0;
  152.             return NULLBUF;
  153.         }
  154.         sp->rbp1 = sp->rbp1->next;
  155.         sp->rcp = sp->rbp1->data;
  156.     }
  157.     /* Store the character, increment fragment and total
  158.      * byte counts
  159.      */
  160.     *sp->rcp++ = c;
  161.     sp->rbp1->cnt++;
  162.     sp->rcnt++;
  163.     return NULLBUF;
  164. }
  165. /* Process SLIP line input */
  166. void
  167. asy_rx(dev,p1,p2)
  168. int dev;
  169. void *p1;
  170. void *p2;
  171. {
  172.     char c;
  173.     struct mbuf *bp,*nbp;
  174.     struct phdr *phdr;
  175.     struct slip *sp;
  176.  
  177.     sp = &Slip[dev];
  178.  
  179.     for(;;){
  180.         c = Slip[dev].get(Slip[dev].iface->dev);
  181.         if((bp = slip_decode(dev,c)) == NULLBUF)
  182.             continue;    /* More to come */
  183.  
  184.         if((nbp = pushdown(bp,sizeof(struct phdr))) == NULLBUF){
  185.             free_p(bp);
  186.             continue;
  187.         }
  188.         phdr = (struct phdr *)nbp->data;
  189.         phdr->iface = sp->iface;
  190.         phdr->type = sp->type;
  191.         enqueue(&Hopper,nbp);
  192.     }
  193. }
  194.